use anyhow::Error;
use thiserror::Error;

use crate::{CommonConfigError, CommonStrategyError};

/// 引导流程统一错误类型
///
/// 覆盖阶段执行、提供器执行、配置缺失等常见失败场景，便于上层定位问题。
#[derive(Error, Debug)]
pub enum BootstrapError {
    /// 某个阶段执行失败
    #[error("阶段执行失败: {stage}")]
    StageFailure {
        stage: &'static str,
        #[source]
        source: Error,
    },
    /// 某个 provider 执行失败
    #[error("提供器执行失败: {provider}")]
    ProviderFailure {
        provider: &'static str,
        #[source]
        source: Error,
    },
    /// 缺少规则加载器
    #[error("缺少规则加载器，请至少注册一个规则加载阶段")]
    MissingRuleLoader,
    /// 配置不合法或缺失
    #[error("无效配置: {0}")]
    InvalidConfiguration(String),
}

impl BootstrapError {
    /// 构造阶段执行失败错误
    pub fn stage_failure(
        stage: &'static str,
        source: Error,
    ) -> Self {
        Self::StageFailure { stage, source }
    }

    /// 构造提供器执行失败错误
    pub fn provider_failure(
        provider: &'static str,
        source: Error,
    ) -> Self {
        Self::ProviderFailure { provider, source }
    }
}

impl From<CommonConfigError> for BootstrapError {
    fn from(value: CommonConfigError) -> Self {
        Self::InvalidConfiguration(value.to_string())
    }
}

impl From<CommonStrategyError> for BootstrapError {
    fn from(value: CommonStrategyError) -> Self {
        Self::InvalidConfiguration(value.to_string())
    }
}
